package com.maimao.goods.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.maimao.core.constant.Constants;
import com.maimao.core.constant.RedisKeys;
import com.maimao.core.exception.MaiMaoDaoException;
import com.maimao.core.model.resp.PageResult;
import com.maimao.core.utils.PinYinUtils;
import com.maimao.goods.client.UploadClient;
import com.maimao.goods.mapper.CateMapper;
import com.maimao.model.goods.Category;
import com.maimao.model.goods.input.CateSearch;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static cn.hutool.core.collection.CollUtil.*;
import static cn.hutool.core.util.ObjectUtil.equal;
import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList;

/**
 * @author MaoLin Wang
 * @date 2020/12/11 3:19 下午
 */
@Service
public class CateService {
    @Autowired
    private CateMapper cateMapper;

    @Autowired
    private UploadClient uploadClient;


    @Autowired
    private RedisTemplate redisTemplate;

    public PageResult<Category> searchData(Integer page, Integer size, CateSearch cateSearch) {
        PageHelper.startPage(page, size);
        List<Category> categories = cateMapper.searchByParams(cateSearch);

        if (ObjectUtil.isNotEmpty(categories)) {
            categories.stream().forEach(category -> {
                Integer level = category.getLevel();
                if (level > 2) {
                    int plevel = category.getLevel() - 1;//3
                    ArrayList<Integer> pidsTemp = toList(category.getPid());
                    int pid = category.getPid();
                    for (int i = 0; i < level - 2; i++) {
                        if (plevel == 1) {
                            break;
                        }
                        Category pcate = cateMapper.selectById(pid);
                        pidsTemp.add(pcate.getPid());
                        pid = pcate.getPid();
                        plevel = pcate.getLevel() - 1;//2
                    }
                    category.setPidTemp(reverse(pidsTemp));
                } else {
                    category.setPidTemp(toList(category.getPid()));
                }
            });
        }
        PageResult<Category> pageResult = new PageResult<>(categories);
        return pageResult;

    }

    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void add(Category category, List<String> deletePics) {
        setPinYinAndLevelAndDelPic(category, deletePics);

        cateMapper.insert(category);

        redisTemplate.delete(RedisKeys.CATEGORY_KEY);
    }

    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void update(Category category, List<String> deletePics) {
        setPinYinAndLevelAndDelPic(category, deletePics);

        cateMapper.updateById(category);

        redisTemplate.delete(RedisKeys.CATEGORY_KEY);
    }

    /**
     * 更新状态
     *
     * @param id     分类id
     * @param status 要更改的状态
     */
    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void updateStatus(Integer id, int status) {
        cateMapper.updateStatusBatch(CollUtil.newArrayList(id), status);
        // 停用时目前无需停用所有子分类，因为在相关功能查询时，如果分类停用，则不会查询到其子分类
        if (equal(status, Constants.ONE)) {
            //启用分类 需将该分类下的所有子分类都启用
            List<Category> categories = cateMapper.selectTreeAll(id);
            if (isNotEmpty(categories)) {
                List<Integer> ids = Lists.newArrayListWithCapacity(categories.size());
                findChildIds(categories, ids);
                if (isNotEmpty(ids)) {
                    cateMapper.updateStatusBatch(ids, status);
                }
            }
        }
        redisTemplate.delete(RedisKeys.CATEGORY_KEY);


    }


    public List<Category> treeData() {
        List<Category> categories = redisTemplate.opsForList().range(RedisKeys.CATEGORY_KEY, 0, -1);
        if (categories == null || categories.size() <= 0) {
            List<Category> categoryList = cateMapper.selectTree(0);
            redisTemplate.opsForList().rightPushAll(RedisKeys.CATEGORY_KEY, categoryList);
            redisTemplate.expire(RedisKeys.CATEGORY_KEY, 7, TimeUnit.DAYS);
            return categoryList;
        } else {
            return categories;
        }
    }


    public List<Integer> searchIdsByKey(String key) {
        return cateMapper.searchIdsByKey(key);
    }

    public List<String> selectNamesByIds(List<Integer> ids) {
        return cateMapper.selectNamesByIds(ids);
    }

    public List<Category> selectBatch(List<Integer> ids) {
        return cateMapper.selectBatchByIds(ids);
    }


    //----------- private method ----------------------//

    /**
     * 设置拼音、首字母、分类等级并删除多余图片
     */
    private void setPinYinAndLevelAndDelPic(Category category, List<String> deletePics) {
        String pinyin = PinYinUtils.getPingYin2Json(category.getName(), "/");
        String head = PinYinUtils.getPingYinHead2Json(category.getName(), "/");
        category.setPinyin(pinyin);
        category.setHead(head);

        Category parent = cateMapper.selectById(category.getPid());

        if (parent != null) {
            category.setLevel(parent.getLevel() + 1);
        }

        if (ObjectUtils.isNotEmpty(deletePics)) {
            uploadClient.deleteBatch(deletePics);
        }
    }

    /**
     * 获取包括categories所有子节点的数据id
     *
     * @param categories 要遍历的数据
     * @param ids        id存储到该集合
     */
    private void findChildIds(List<Category> categories, List<Integer> ids) {
        ids.addAll(categories.stream().map(Category::getId).collect(Collectors.toList()));
        for (Category category : categories) {
            if (isNotEmpty(category.getChildren())) {
                findChildIds(category.getChildren(), ids);
            }
        }
    }


    /**
     * 根据品牌ID查询1-3级所有分类ID
     *
     * @param brandId 品牌ID
     */
    public List<Integer> selectCid123ByBrandId(Long brandId) {
        List<Integer> cid3s = cateMapper.selectIdsByBrandId(brandId);
        if (ObjectUtil.isNotEmpty(cid3s)) {
            Set<Integer> cid2s = cateMapper.selectPidByIdBatch(cid3s);
            Set<Integer> cid1s = cateMapper.selectPidByIdBatch(Lists.newArrayList(cid2s));
            cid3s.addAll(cid2s);
            cid3s.addAll(cid1s);
        }
        return cid3s;
    }
}
